﻿using MesShell.Utils;
using Microsoft.Extensions.Logging;
using PluginInterface;

namespace PLC.Http
{
    [DriverSupported("A_1E")]
    [DriverSupported("Qna_3E")]
    [DriverInfo("DeviceHttp", "V1.0.0", "Copyright IoTGateway.net 20230220")]
    public class DeviceHttp : IHttpDriver
    {

        public ILogger _logger { get; set; }
        private readonly string _device;

        #region 配置参数

        [ConfigParameter("设备Id")] public string DeviceId { get; set; }


        [ConfigParameter("下载地址")] public string DownloadUrl { get; set; }

        [ConfigParameter("上传地址")] public string UploadUrl { get; set; }

        [ConfigParameter("超时时间ms")] public int Timeout { get; set; } = 3000;

        [ConfigParameter("最小通讯周期ms")] public uint MinPeriod { get; set; } = 3000;

        #endregion 配置参数

        #region 生命周期

        /// <summary>
        /// 反射构造函数
        /// </summary>
        /// <param name="device"></param>
        /// <param name="logger"></param>
        public DeviceHttp(string device, ILogger logger)
        {
            _device = device;
            _logger = logger;

            _logger.LogInformation($"Device:[{_device}],Create()");
        }

        /// <summary>
        /// 连接状态
        /// </summary>
        public bool IsConnected => true;

        /// <summary>
        /// 连接
        /// </summary>
        /// <returns></returns>
        public bool Connect()
        {
            try
            {
                _logger.LogInformation($"Device:[{_device}],Connect()");

            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Device:[{_device}],Connect(),Error");
                return false;
            }

            return IsConnected;
        }

        /// <summary>
        /// 断开
        /// </summary>
        /// <returns></returns>
        public bool Close()
        {
            try
            {
                _logger.LogInformation($"Device:[{_device}],Close()");


                return !IsConnected;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Device:[{_device}],Close(),Error");
                return false;
            }
        }

        /// <summary>
        /// 释放
        /// </summary>
        public void Dispose()
        {
            try
            {
                _logger.LogInformation($"Device:[{_device}],Dispose()");

                // Suppress finalization.
                GC.SuppressFinalize(this);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Device:[{_device}],Dispose(),Error");
            }
        }

        #endregion 生命周期

        #region 读写方法

        /// <summary>
        /// 读
        /// </summary>
        /// <param name="ioArg"></param>
        /// <returns></returns>
        [Method("读PLC标准地址", description: "读PLC标准地址")]
        public DriverReturnValueModel Read(DriverAddressIoArgModel ioArg)
        {
            var ret = new DriverReturnValueModel { StatusType = VaribaleStatusTypeEnum.Good };
            // Console.WriteLine("Read");
            // Console.WriteLine(ioArg.Address);

            // Console.WriteLine(string.Join(",", _cache.Keys.ToArray()));

            if (_cache.ContainsKey(ioArg.Address))
            {
                ret.StatusType = VaribaleStatusTypeEnum.Good;
                ret.Value = _cache[ioArg.Address];
            }
            else if (keys.Contains(ioArg.Address))
            {
                ret.StatusType = VaribaleStatusTypeEnum.Good;
                ret.Value = "";
            }
            else
            {   
                ret.StatusType = VaribaleStatusTypeEnum.Bad;
                ret.Value = "";
            }

            return ret;
        }

        private Dictionary<string, string> _cache = new();

        /// <summary>
        /// 写
        /// </summary>
        /// <param name="requestId"></param>
        /// <param name="method"></param>
        /// <param name="ioArg"></param>
        /// <returns></returns>
        public async Task<RpcResponse> WriteAsync(string requestId, string method, DriverAddressIoArgModel ioArg)
        {
            RpcResponse rpcResponse = new() { IsSuccess = false, Description = "设备驱动内未实现写入功能" };
            await Task.CompletedTask;
            return rpcResponse;
        }



        #endregion 读写方法
        string[] keys = new string[] { "Download_Input", "Download_Output", "Upload_Input", "Upload_Output" };
        public async Task<string> PostDownloadUrl(string jsonData, string site)
        {
            try
            {
                _cache["Download_Input"] = "" + jsonData.Replace("\"", "\'") + "";
                _cache["Download_Output"] = string.Empty;

                // Console.WriteLine("Download_Input");
                // Console.WriteLine(jsonData);

                var rs = await HttpUtils.Post(this.DownloadUrl, jsonData,site);

                _cache["Download_Output"] = "" + rs.Replace("\"", "\'") + "";
                return rs;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Device:[{_device}],PostDownloadUrl(),Error");
                return string.Empty;
            }
        }

        public async Task<string> PostUploadUrl(string jsonData, string site)
        {
            try
            {
                _cache["Upload_Input"] = "" + jsonData.Replace("\"","\'") + "";
                _cache["Upload_Output"] = string.Empty;
                
                var rs = await HttpUtils.Post(this.UploadUrl, jsonData,site);

                _cache["Upload_Output"] = "" + rs.Replace("\"", "\'") + "";

                return rs;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Device:[{_device}],PostUploadUrl(),Error");
                return string.Empty;
            }

        }
    }
}